<?php
//
//	file: includes/attach/class_attach_privmsg.php
//	author: ptirhiik
//	begin: 05/03/2006
//	version: 1.6.3 - 09/02/2007
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//
//	based on : attachment_mod copyright (c) 2002 Meik Sievertsen (acydburn)
//

if ( !defined('IN_PHPBB') )
{
	die('Hack attempt !');
}

class attach_privmsg extends attach_parent
{
	var $folder;
	var $post_id;
	var $delete_attach;

	// Constructor
	function attach_privmsg()
	{
		global $HTTP_POST_VARS, $refresh;
		parent::attach_parent(PAGE_PRIVMSGS);
		$this->delete_attach = false;
	}

	function start()
	{
		global $refresh, $folder, $mode;

		$refresh |= $this->action();
		$this->folder = $folder;
		parent::init();
		if ( empty($mode) )
		{
			$this->display_attach_box_limits();
		}

		// handle the delete pm attachments button
		if ( $this->delete_attach = _on_form('pm_delete_attach') )
		{
			$mode = 'read';
			_force_url(POST_POST_URL, intval($mark_list[0]));
		}
		return true;
	}

	function delete($ids)
	{
		return $this->delete_all($ids);
	}

	function duplicate($privmsg, $to_privmsgs_id)
	{
		if ( intval($to_privmsgs_id) && isset($privmsg['privmsgs_id']) && intval($privmsg['privmsgs_id']) && isset($privmsg['privmsgs_attachment']) && $privmsg['privmsgs_attachment'] )
		{
			$this->plug_duplicate(intval($privmsg['privmsgs_id']), intval($to_privmsgs_id));
		}
		return true;
	}

	function display_message($privmsg, $privmsgs_id)
	{
		if ( $this->delete_attach )
		{
			$this->delete($privmsgs_id);
		}

		// display the attachments
		if ( isset($privmsg['privmsgs_attachment']) && $privmsg['privmsgs_attachment'] )
		{
			$attachment_pm_display = new attach_display_privmsg();
			$attachment_pm_display->plug_read(true, $privmsg);
			$attachment_pm_display->display();
			$attachment_pm_display->update_views();
			unset($attachment_pm_display);
		}
		return true;
	}

	function submit()
	{
		global $mode, $privmsg_id, $privmsg_sent_id, $to_userdata;
		global $user;

		return $this->validate($mode, $mode == 'edit' ? intval($privmsg_id) : intval($privmsg_sent_id), $user->data['user_id'], intval($to_userdata['user_id']));
	}

	function set_form()
	{
		global $template;
		global $mode, $privmsg_id;

		$this->process($mode, $privmsg_id);
		$template->set_switch('left_part', $this->is_active);
		$template->set_switch('attachment_form', $this->is_active);
		return true;
	}

	function preview()
	{
		global $mode, $privmsg_id;
		global $config;

		if ( $this->is_active )
		{
			if ( !$this->processed )
			{
				$this->process($mode, $privmsg_id, true);
			}
			if ( !empty($this->data) )
			{
				$preview = new attach_display_privmsg();
				$preview->data[0] = &$this->data;
				$preview->display_main();
				$config->globals['mod_attachment_CH']['extensions']->read();
				$preview->display(0, 'preview');
				unset($preview);
			}
		}
	}

	function format_rows(&$rows)
	{
		return $this->get_images($rows);
	}

	function display_row(&$row)
	{
		global $template;
		$template->set_switch('listrow.attach', isset($row['privmsgs_attach_icon']) && $row['privmsgs_attach_icon']);
		return true;
	}

	// Display the Attach Limit Box (move it to displaying.php ?)
	function display_attach_box_limits()
	{
		global $user, $template, $config;

		if ( !$this->is_active || ($this->folder == 'outbox') )
		{
			return;
		}

		$this->get_quota_limits($user->data, PAGE_PRIVMSGS);
		$template->assign_vars(array('ATTACH_QUOTA_BOX' => get_quota_box('Attachbox_limit', $this->get_total_filesize(intval($user->data['user_id'])), doubleval($config->globals['mod_attachment_CH']['config']->data['pm_filesize_limit']) ? doubleval($config->globals['mod_attachment_CH']['config']->data['pm_filesize_limit']) : doubleval($config->globals['mod_attachment_CH']['config']->data['attachment_quota']))));
	}

	function get_images(&$rows)
	{
		global $db, $template, $config, $user;

		if ( empty($rows) || intval($config->globals['mod_attachment_CH']['config']->data['disable_mod']) || (($user->data['user_level'] != ADMIN) && !intval($config->globals['mod_attachment_CH']['config']->data['allow_pm_attach'])) )
		{
			return;
		}
		// choose the icon
		$attach_icon = isset($user->global_images['topic_attach_tiny']) ? $user->img('topic_attach_tiny') : (empty($config->globals['mod_attachment_CH']['config']->data['topic_icon']) ? '' : $config->root . $config->globals['mod_attachment_CH']['config']->data['topic_icon']);
		if ( empty($attach_icon) )
		{
			return;
		}
		$template->assign_vars(array(
			'I_ATTACH' => $attach_icon,
		));

		// get pms with attachments
		$sql = 'SELECT DISTINCT privmsgs_id
					FROM ' . ATT_LINKS_TABLE . '
					WHERE privmsgs_id IN(' . implode(', ', array_keys($rows)) . ')';
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		while ( $row = $db->sql_fetchrow($result) )
		{
			$rows[ intval($row['privmsgs_id']) ]['privmsgs_attach_icon'] = true;
		}
		$db->sql_freeresult($result);
	}

	// @private
	function get_auth()
	{
		global $user, $config;

		$this->is_auth = array();
		if ( $user->data['user_level'] == ADMIN )
		{
			$this->is_auth['auth_attachments'] = true;
			$this->is_auth['auth_edit'] = true;
			$this->is_auth['auth_mod'] = true;
		}
		else
		{
			$this->is_auth['auth_attachments'] = intval($config->globals['mod_attachment_CH']['config']->data['allow_pm_attach']);
			$this->is_auth['auth_edit'] = $this->is_auth['auth_attachments'];
			$this->is_auth['auth_mod'] = false;
		}
	}

	// @private
	function get_attachments($privmsgs_id)
	{
		global $db;

		$sql = 'SELECT a.privmsgs_id, d.*
					FROM ' . ATT_LINKS_TABLE . ' a, ' . ATT_DESC_TABLE . ' d
					WHERE d.attach_id = a.attach_id
						AND a.post_id = 0
						AND a.privmsgs_id = ' . intval($privmsgs_id) . '
					ORDER BY d.filetime DESC';
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		$attachments = array();
		while ( $row = $db->sql_fetchrow($result) )
		{
			$attachments[ intval($row['privmsgs_id']) ][ intval($row['attach_id']) ] = $row;
		}
		$db->sql_freeresult($result);
		return $attachments;
	}

	// @private
	function get_rules_id()
	{
		return 0;
	}

	// @private
	function check_extension_auth()
	{
		return true;
	}

	// @private
	function get_total_filesize($user_id)
	{
		global $db;
		if ( !intval($user_id) )
		{
			return;
		}

		//
		// get the pms from all the user's boxes (except sent box... hum... well no, include it : the sent box has also to be cleaned up)
		//
		$from_user = array(PRIVMSGS_SENT_MAIL, PRIVMSGS_NEW_MAIL, PRIVMSGS_SAVED_OUT_MAIL);
		$to_user = array(PRIVMSGS_READ_MAIL, PRIVMSGS_NEW_MAIL, PRIVMSGS_UNREAD_MAIL, PRIVMSGS_SAVED_IN_MAIL);
		$sql = 'SELECT SUM(d.filesize) AS sum_filesize
					FROM ' . ATT_DESC_TABLE . ' d, ' . ATT_LINKS_TABLE . ' a, ' . PRIVMSGS_TABLE . ' p
					WHERE d.attach_id = a.attach_id
						AND p.privmsgs_id = a.privmsgs_id
						AND a.post_id = 0
						AND ((p.privmsgs_from_userid = ' . intval($user_id) . ' AND p.privmsgs_type IN(' . implode(', ', $from_user) . '))
							OR (p.privmsgs_to_userid = ' . intval($user_id) . ' AND p.privmsgs_type IN(' . implode(', ', $to_user) . ')))';
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		$total_filesize = ($row = $db->sql_fetchrow($result)) ? doubleval($row['sum_filesize']) : 0;
		$db->sql_freeresult($result);

		return $total_filesize;
	}

	// @private
	function check_user_quota($filesize)
	{
		global $error, $error_msg, $HTTP_POST_VARS;
		global $db, $user, $config;

		$this->get_quota_limits($user->data, PAGE_PRIVMSGS);
		if ( doubleval($config->globals['mod_attachment_CH']['config']->data['pm_filesize_limit']) )
		{
			$total_filesize = $this->get_total_filesize(intval($user->data['user_id']));
			if ( ($total_filesize + $filesize) > doubleval($config->globals['mod_attachment_CH']['config']->data['pm_filesize_limit']) )
			{
				_error('Attach_quota_sender_pm_reached');
			}
		}
				
		// Check Receivers PM Quota
		$to_user = isset($HTTP_POST_VARS['username']) ? $HTTP_POST_VARS['username'] : '';
		if ( !empty($to_user) && ($user->data['user_level'] != ADMIN) )
		{
			$u_data = get_userdata($to_user, true);
			if ( $u_data )
			{
				$this->get_quota_limits($u_data, PAGE_PRIVMSGS);
				if ( doubleval($config->globals['mod_attachment_CH']['config']->data['pm_filesize_limit']) )
				{
					$total_filesize = $this->get_total_filesize(intval($to_user['user_id']));
					if ( ($total_filesize + $filesize) > doubleval($config->globals['mod_attachment_CH']['config']->data['pm_filesize_limit']) )
					{
						_error(sprintf($user->lang('Attach_quota_receiver_pm_reached'), $to_user));
					}
				}
			}
		}
	}

	function get_mode($mode)
	{
		if ( ($mode == 'quote') || ($mode == 'reply') )
		{
			$mode = 'reply';
			$this->post_id = 0;
		}
		if ( ($mode == 'post') || ($mode == 'newtopic') )
		{
			$mode = 'newtopic';
			$this->post_id = 0;
		}
		if ( ($mode == 'edit') || ($mode == 'editpost') )
		{
			$mode = 'editpost';
		}
		return $mode;
	}

	function validate($mode, $post_ids, $from_user_id=0, $to_user_id=0, $post_attachment=false)
	{
		global $template, $lang, $userdata, $HTTP_POST_VARS, $phpbb_root_path, $phpEx, $db;
		global $confirm, $delete, $delete_all, $privmsgs_id, $privmsg_id, $submit, $folder, $mark_list, $folder;
		global $user, $config;

		$mode = $this->get_mode($mode);
		switch( $mode )
		{
			case 'editpost':
			case 'newtopic':
			case 'reply':
				if ( $this->is_active && !empty($post_ids) && !is_array($post_ids) )
				{
					if ( !$this->processed )
					{
						$this->process($mode, $post_ids, true);
					}
					if ( $error )
					{
						message_die(GENERAL_MESSAGE, $error_msg);
					}
					$link = array(
						'post_id' => 0,
						'privmsgs_id' => (int) $post_ids,
						'user_id' => (int) $from_user_id,
					);
					if ( $this->submit_all($link) )
					{
						$this->resync($post_ids);
					}
				}
				break;

			case 'delete':
				$this->delete_all($post_ids);
				break;

			case 'duplicate':
				if ( !empty($post_ids) && (count($post_ids) == 2) && $post_attachment )
				{
					$this->plug_duplicate(intval($post_ids[0]), intval($post_ids[1]));
				}
				break;
		}
	}

	function plug_duplicate($post_id, $to_post_id)
	{
		global $db;
		if ( !intval($post_id) || !intval($to_post_id) )
		{
			return;
		}
		$sql = 'SELECT *
					FROM ' . ATT_LINKS_TABLE . '
					WHERE privmsgs_id = ' . intval($post_id);
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		$db->sql_stack_reset();
		$found = false;
		while ( $row = $db->sql_fetchrow($result) )
		{
			$found = true;
			$fields = array(
				'attach_id' => intval($row['attach_id']),
				'post_id' => 0,
				'privmsgs_id' => intval($to_post_id),
				'user_id' => intval($row['user_id']),
			);
			$db->sql_stack_statement($fields);
		}
		$db->sql_freeresult($result);
		$db->sql_stack_insert(ATT_LINKS_TABLE, false, __LINE__, __FILE__);
		if ( $found )
		{
			$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
						SET privmsgs_attachment = 1
						WHERE privmsgs_id = ' . intval($to_post_id);
			$db->sql_query($sql, false, __LINE__, __FILE__);
		}
	}

	function delete_all($post_ids)
	{
		global $db;

		if ( empty($post_ids) )
		{
			return;
		}
		if ( !is_array($post_ids) )
		{
			$post_ids = array($post_ids);
		}
		$post_ids = array_map('intval', $post_ids);
		$found = false;

		// read all physical name
		$sql = 'SELECT d.attach_id, d.physical_filename, d.thumbnail
					FROM ' . ATT_DESC_TABLE . ' d, ' . ATT_LINKS_TABLE . ' a
					WHERE d.attach_id = a.attach_id
						AND a.privmsgs_id IN(' . implode(', ', $post_ids) . ')
						AND a.post_id = 0';
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		$files = array();
		while ( $row = $db->sql_fetchrow($result) )
		{
			$files[ intval($row['attach_id']) ] = array('physical_filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail']);
		}
		$db->sql_freeresult($result);

		if ( !empty($files) )
		{
			// delete the links to the pm
			$sql = 'DELETE FROM ' . ATT_LINKS_TABLE . '
						WHERE privmsgs_id IN(' . implode(', ', $post_ids) . ')
							AND post_id = 0';
			$db->sql_query($sql, false, __LINE__, __FILE__);

			// is the file shared ? if so, don't delete it
			$sql = 'SELECT DISTINCT attach_id
						FROM ' . ATT_LINKS_TABLE . '
						WHERE attach_id IN(' . implode(', ', array_keys($files)) . ')';
			$result = $db->sql_query($sql, false, __LINE__, __FILE__);
			while ( $row = $db->sql_fetchrow($result) )
			{
				unset($files[ intval($row['attach_id']) ]);
			}
			$db->sql_freeresult($result);
		}

		// delete the files on the ftp
		if ( !empty($files) )
		{
			if ( $this->handler->open_channel() )
			{
				foreach ($files as $attach_id => $file )
				{
					$this->handler->unlink($file['physical_filename'], $file['thumbnail']);
				}
				$this->handler->close_channel();
			}
			$attach_ids = array_keys($files);
			unset($files);

			// delete the files description
			$sql = 'DELETE FROM ' . ATT_DESC_TABLE . '
						WHERE attach_id IN(' . implode(', ', $attach_ids) . ')';
			$db->sql_query($sql, false, __LINE__, __FILE__);
			unset($attach_ids);

			$found = true;
		}
		return $found;
	}

	function delete_one($post_id, $attach_id)
	{
		global $db;

		if ( empty($this->data) || !isset($this->data[ intval($attach_id) ]) )
		{
			return;
		}

		// remove the link to the post if exists
		if ( intval($post_id) )
		{
			$sql = 'DELETE FROM ' . ATT_LINKS_TABLE . '
						WHERE privmsgs_id = ' . intval($post_id) . '
							AND attach_id = ' . intval($attach_id);
			$db->sql_query($sql, false, __LINE__, __FILE__);
		}

		// is the file shared ?
		$found = false;
		if ( !$this->data[ intval($attach_id) ]['pending'] )
		{
			$sql = 'SELECT attach_id
						FROM ' . ATT_LINKS_TABLE . '
						WHERE attach_id = ' . intval($attach_id) . '
						LIMIT 1';
			$result = $db->sql_query($sql, false, __LINE__, __FILE__);
			$found = $db->sql_numrows($result);
			$db->sql_freeresult($result);
		}

		// remove the file if not shared
		if ( !$found )
		{
			if ( $this->handler->open_channel() )
			{
				$this->handler->unlink($this->data[ intval($attach_id) ]['physical_filename'], $this->data[ intval($attach_id) ]['thumbnail']);
				$this->handler->close_channel();
			}

			// delete desc
			$sql = 'DELETE FROM ' . ATT_DESC_TABLE . '
						WHERE attach_id = ' . intval($attach_id);
			$db->sql_query($sql, false, __LINE__, __FILE__);
		}

		// adjust the post if exists
		if ( $post_id && !$this->data[ intval($attach_id) ]['pending'] )
		{
			// is there a non pending attachment remaining ?
			$sav_data = $this->data;
			unset($sav_data[ intval($attach_id) ]);
			$found = !empty($sav_data);
			unset($sav_data);

			// resync post and topic
			if ( !$found )
			{
				$sav_data = $this->data;
				$this->data = array();
				$this->resync($post_id);
				$this->data = $sav_data;
			}
		}
	}

	function resync($post_id=0)
	{
		global $db;

		$found = empty($this->data) ? 0 : 1;
		if ( intval($post_id) )
		{
			$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
						SET privmsgs_attachment = ' . intval($found) . '
						WHERE privmsgs_id = ' . intval($post_id);
			$db->sql_query($sql, false, __LINE__, __FILE__);
		}
	}
}

?>